<template>
  <div>
    <div ref="vtkContainer" style="width: 100%; height: 100vh;"></div>
  </div>
</template>

<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount } from "vue";

// 导入 vtk.js 相关模块
import vtkFullScreenRenderWindow from "@kitware/vtk.js/Rendering/Misc/FullScreenRenderWindow";
import vtkArrowSource from "@kitware/vtk.js/Filters/Sources/ArrowSource";
import vtkGlyph3DMapper from "@kitware/vtk.js/Rendering/Core/Glyph3DMapper";
import vtkActor from "@kitware/vtk.js/Rendering/Core/Actor";
import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData";
import vtkPoints from "@kitware/vtk.js/Common/Core/Points";
import vtkDataArray from "@kitware/vtk.js/Common/Core/DataArray";

const vtkContainer = ref(null); // 容器引用
const context = ref(null); // 存储 vtk.js 上下文

onMounted(() => {
  if (!context.value) {
    // 创建全屏渲染窗口
    const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance({
      rootContainer: vtkContainer.value, // 绑定到 DOM 容器
      background: [0.1, 0.1, 0.1], // 设置背景颜色为深色
    });

    const { renderer, renderWindow } = fullScreenRenderer;

    try {
      // 创建箭头源用于表示水流速度
      const arrowSource = vtkArrowSource.newInstance();

      // 创建点（流场中的位置）
      const points = vtkPoints.newInstance();
      const velocities = [];
      const velocityMagnitudes = [];
      const numPoints = 50; // 设置流场中的点数量
      for (let i = 0; i < numPoints; i++) {
        // 创建一些随机的点，模拟水流
        points.insertNextPoint(Math.random(), Math.random(), Math.random());
        // 随机生成流速方向的矢量
        const vx = Math.random() * 2 - 1;
        const vy = Math.random() * 2 - 1;
        const vz = Math.random() * 2 - 1;
        velocities.push(vx, vy, vz);
        // 计算流速矢量的模长，用于缩放
        const magnitude = Math.sqrt(vx * vx + vy * vy + vz * vz);
        velocityMagnitudes.push(magnitude);
      }

      // 创建 PolyData，包含流场中的点
      const polyData = vtkPolyData.newInstance();
      polyData.setPoints(points);

      // 将流速数据作为矢量字段添加到 PolyData 中
      const velocityArray = vtkDataArray.newInstance({
        numberOfComponents: 3, // 流速矢量有三个分量（x, y, z）
        values: velocities, // 流速矢量值
        name: 'velocity', // 矢量字段的名称
      });
      polyData.getPointData().setVectors(velocityArray); // 将矢量字段设置为点数据的矢量

      // 将流速的模长添加为标量数据（用于缩放）
      const magnitudeArray = vtkDataArray.newInstance({
        numberOfComponents: 1, // 标量
        values: velocityMagnitudes, // 模长值
        name: 'magnitude', // 名称
      });
      polyData.getPointData().setScalars(magnitudeArray); // 将模长设置为标量字段

      // 创建 Glyph3DMapper 将箭头与流速矢量进行映射
      const glyphMapper = vtkGlyph3DMapper.newInstance();
      glyphMapper.setInputData(polyData); // 设置输入的 PolyData（点数据和流速矢量）
      glyphMapper.setOrientationArray('velocity'); // 使用流速矢量作为方向

      // 设置缩放数组为流速模长
      // glyphMapper.setScaleArray('magnitude');
      // glyphMapper.setScaling(true); // 启用缩放
      glyphMapper.setScaleFactor(0.1); // 设置缩放比例

      glyphMapper.setSourceConnection(arrowSource.getOutputPort()); // 设置箭头作为几何源

      // 添加调试日志，确保 mapper 正确配置
      console.log('glyphMapper configured: ', glyphMapper);

      // 创建 Actor 进行渲染
      const actor = vtkActor.newInstance();
      actor.setMapper(glyphMapper); // 将 Mapper 绑定到 Actor

      // 将 Actor 添加到渲染器中
      renderer.addActor(actor);

      // 设置相机视角并渲染场景
      renderer.resetCamera();
      renderWindow.render();

      // 将上下文存储起来，以便在卸载时进行清理
      context.value = {
        fullScreenRenderer,
        actor,
        arrowSource,
        polyData,
        glyphMapper,
      };

    } catch (error) {
      console.error("Error during vtk.js setup: ", error);
    }
  }
});

onBeforeUnmount(() => {
  // 组件卸载时，清理 vtk.js 对象
  if (context.value) {
    const { fullScreenRenderer, actor, arrowSource, polyData, glyphMapper } = context.value;
    actor.delete();
    arrowSource.delete();
    polyData.delete();
    glyphMapper.delete();
    fullScreenRenderer.delete();
    context.value = null;
  }
});
</script>

<style lang="scss">
/* 简单的全屏样式，确保 vtk 容器充满整个视口 */
html, body, #app {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
}
</style>
